package org.xxpay.pay.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.*;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.xxpay.core.common.util.MyLog;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public class MyHttp {

    private static final MyLog _log = MyLog.getLog(MyHttp.class);

    /**
     * post请求 json 格式
     *
     * @param url
     * @param jsonObject object
     * @return json object
     */
    public static JSONObject doPost4Json(String url, JSONObject jsonObject) {
        _log.info(jsonObject.toJSONString());
        HttpClient client = HttpClientBuilder.create().build();
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(60 *1000) // 设置连接超时时间，单位毫秒
                .setSocketTimeout(60 *1000)  // 请求获取数据的超时时间
                .setConnectionRequestTimeout(60 * 1000)  // 设置从connect Manager 获取connection 超时时间
                .build();
        HttpPost post = new HttpPost(url);
        post.setConfig(requestConfig);
        JSONObject response = null;
        try{
            StringEntity s = new StringEntity(jsonObject.toString(), "utf-8");
            s.setContentEncoding("UTF-8");
            s.setContentType("application/json");
            post.setEntity(s);
            HttpResponse res = client.execute(post);
            if (res.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                HttpEntity entity = res.getEntity();
                String result = EntityUtils.toString(entity);
                response = JSONObject.parseObject(result);
            }else{
                _log.error("http_post请求返回码：" + res.getStatusLine().getStatusCode());
            }
        } catch (Exception e) {
            _log.error(e, "");
        }
        return response;
    }

    public static JSONObject doGet4Json(String url) {
        HttpClient httpClient = HttpClientBuilder.create().build();
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(60 *1000) // 设置连接超时时间，单位毫秒
                .setSocketTimeout(60 *1000)  // 请求获取数据的超时时间
                .setConnectionRequestTimeout(60 * 1000)  // 设置从connect Manager 获取connection 超时时间
                .build();
        HttpGet get = new HttpGet(url);
        get.setConfig(requestConfig);
        JSONObject response = null;
        try {
            HttpResponse res = httpClient.execute(get);
            if (res.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                HttpEntity entity = res.getEntity();
                String result = EntityUtils.toString(entity);
                response = JSONObject.parseObject(result);
            }else{
                _log.error("http_get请求返回码：" + res.getStatusLine().getStatusCode());
            }
        } catch (Exception e) {
            _log.error(e, "");
        }
        return response;
    }

    public static String doPost(String url) {
        Map<String, String> param = null;
        return doPost(url, param);
    }

    public static String doPost(String url, Map<String, String> param) {
        // 创建Httpclient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(60 *1000) // 设置连接超时时间，单位毫秒
                .setSocketTimeout(60 *1000)  // 请求获取数据的超时时间
                .setConnectionRequestTimeout(60 * 1000)  // 设置从connect Manager 获取connection 超时时间
                .build();

        CloseableHttpResponse response = null;
        String resultString = "";
        // 创建Http Post请求
        HttpPost httpPost = new HttpPost(url);
        httpPost.setConfig(requestConfig);
        try {
            // 创建参数列表
            if (param != null) {
                List<NameValuePair> paramList = new ArrayList<>();
                for (String key : param.keySet()) {
                    paramList.add(new BasicNameValuePair(key, param.get(key)));
                }
                // 模拟表单
                UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList);
                httpPost.setEntity(entity);
            }
            // 执行http请求
            response = httpClient.execute(httpPost);
            resultString = EntityUtils.toString(response.getEntity(), "utf-8");
        } catch (Exception e) {
            _log.error(e, "");
        } finally {
            try {
                if(null != httpClient) httpClient.close();
                if(null != response) response.close();
            } catch (IOException e) {
                _log.error(e, "");
            }
        }
        return resultString;
    }

    public static JSONObject getParam(HttpServletRequest request) {
        String contentType = request.getContentType();
        _log.info("获取http请求数据,contentType={}", contentType);
        if(contentType.startsWith("application/x-www-form-urlencoded") || contentType.startsWith("multipart/form-data") ) {
            return request2Json(request);
        }
        if(contentType.startsWith("application/json")) {
            return requestPayload2Json(request);
        }
        _log.info("不支持的请求头:{}", contentType);
        return null;
    }

    /**
     * 获取application/x-www-form-urlencoded请求头数据
     * @param request
     * @return
     */
    public static JSONObject request2Json(HttpServletRequest request) {
        // 参数Map
        Map properties = request.getParameterMap();
        // 返回值Map
        JSONObject returnObject = new JSONObject();
        Iterator entries = properties.entrySet().iterator();
        Map.Entry entry;
        String name;
        String value = "";
        while (entries.hasNext()) {
            entry = (Map.Entry) entries.next();
            name = (String) entry.getKey();
            Object valueObj = entry.getValue();
            if(null == valueObj){
                value = "";
            }else if(valueObj instanceof String[]){
                String[] values = (String[])valueObj;
                for(int i=0;i<values.length;i++){
                    value = values[i] + ",";
                }
                value = value.substring(0, value.length()-1);
            }else{
                value = valueObj.toString();
            }

            returnObject.put(name, value);
        }
        return returnObject;
    }

    /**
     * 读取流数据获取数据
     * @param request
     * @return
     */
    public static JSONObject requestPayload2Json(HttpServletRequest request){
        StringBuilder sb = new StringBuilder();
        //从请求流中读取数据
        try(BufferedReader reader = request.getReader();)
        {
            char[] buffer = new char[1024];
            int len = 0;
            while((len = reader.read(buffer))!=-1){
                sb.append(buffer,0,len);
            }
        } catch (IOException e) {
            _log.error(e, "");
        }
        if("".equals(sb.toString())) return new JSONObject();
        return JSONObject.parseObject(sb.toString());
    }

}
